package net.zhuike.novel.app.service;

import android.content.Intent;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.widget.Toast;

import com.alibaba.fastjson.JSONObject;

import net.zhuike.novel.app.R;
import net.zhuike.novel.app.RxBus;
import net.zhuike.novel.app.ZhuiKeApplication;
import net.zhuike.novel.app.bean.BookChapterBean;
import net.zhuike.novel.app.bean.BookSit;
import net.zhuike.novel.app.bean.ChapterInfoBean;
import net.zhuike.novel.app.bean.ChapterRead;
import net.zhuike.novel.app.bean.DownloadTaskBean;
import net.zhuike.novel.app.bean.local.BookRepository;
import net.zhuike.novel.app.bean.local.LocalRepository;
import net.zhuike.novel.app.bean.support.DownloadMessage;
import net.zhuike.novel.app.event.DeleteResponseEvent;
import net.zhuike.novel.app.event.DeleteTaskEvent;
import net.zhuike.novel.app.ui.base.BaseRxService;
import net.zhuike.novel.app.ui.utils.BookManager;
import net.zhuike.novel.app.ui.utils.NetworkUtils;
import net.zhuike.novel.app.ui.utils.SiteHelper;
import net.zhuike.novel.app.ui.view.page.TxtChapter;

import org.json.JSONArray;
import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;

import java.io.IOException;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import framework.common.zanetwork.UeHttpUrl;
import framework.common.zanetwork.core.ResponseCallback;
import framework.log.LogUtils;
import io.reactivex.Single;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

/**
 * Created by wq on 17-5-10.
 */

public class DownloadBService extends BaseRxService {
    private static final String TAG = "DownloadBService";
    //加载状态
    private static final int LOAD_ERROR= -1;
    private static final int LOAD_NORMAL= 0;
    private static final int LOAD_PAUSE = 1;
    private static final int LOAD_DELETE = 2; //正在加载时候，用户删除收藏书籍的情况。
    private SiteHelper helper;
    //下载状态
    public static final int STATUS_CONTINUE = DownloadTaskBean.STATUS_LOADING;
    public static final int STATUS_PAUSE = DownloadTaskBean.STATUS_PAUSE;

    //线程池
    private final ExecutorService mSingleExecutor = Executors.newSingleThreadExecutor();
    //加载队列
    private final List<DownloadTaskBean> mDownloadTaskQueue = Collections.synchronizedList(new ArrayList<>());
    //Handler
    private Handler mHandler;

    //包含所有的DownloadTask
    private List<DownloadTaskBean> mDownloadTaskList;

    private OnDownloadListener mDownloadListener;
    private boolean isBusy = false;
    private boolean isCancel = false;
    @Override
    public void onCreate() {
        super.onCreate();
        mHandler = new Handler(getMainLooper());
        //从数据库中获取所有的任务
        mDownloadTaskList = LocalRepository
                .getInstance()
                .getDownloadTaskList();
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return new TaskBuilder();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId){

        //接受创建的DownloadTask
        Disposable disposable = RxBus.getInstance()
                .toObservable(DownloadTaskBean.class)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(
                        (event) ->  {
                            //判断任务是否为轮询标志
                            //判断任务是否存在，并修改任务
                            if (TextUtils.isEmpty(event.getBookId())
                              || !checkAndAlterDownloadTask(event)){
                                addToExecutor(event);
                            }
                        }
                );
        addDisposable(disposable);

        //是否删除数据的问题
        Disposable deleteDisp = RxBus.getInstance()
                .toObservable(DeleteTaskEvent.class)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(
                        (event) -> {
                            //判断是否该数据存在加载列表中
                            boolean isDelete = true;
                            for (DownloadTaskBean bean : mDownloadTaskQueue){
                                if (bean.getBookId().equals(event.collBook.getId())){
                                    isDelete = false;
                                    break;
                                }
                            }
                            //如果不存在则删除List中的task
                            if (isDelete){
                                //
                                Iterator<DownloadTaskBean> taskIt = mDownloadTaskList.iterator();
                                while (taskIt.hasNext()){
                                    DownloadTaskBean task = taskIt.next();
                                    if (task.getBookId().equals(event.collBook.getId())) {
                                        taskIt.remove();
                                    }
                                }
                            }
                            //返回状态
                            RxBus.getInstance().post(new DeleteResponseEvent(isDelete,event.collBook));
                        }
                );
        addDisposable(deleteDisp);
        return super.onStartCommand(intent, flags, startId);
    }


    /**
     * 1. 查看是否任务已存在
     * 2. 修改DownloadTask的 taskName 和 list
     * @return
     */
    private boolean checkAndAlterDownloadTask(DownloadTaskBean newTask){
        boolean isExist = false;
        for (DownloadTaskBean downloadTask : mDownloadTaskList){
            //如果不相同则不往下执行，往下执行都是存在相同的情况
            if (!downloadTask.getBookId().equals(newTask.getBookId())) continue;

            if (downloadTask.getStatus() == DownloadTaskBean.STATUS_FINISH){
                //判断是否newTask是已完成
                if (downloadTask.getLastChapter() == newTask.getLastChapter()){
                    isExist = true;

                    //发送回去已缓存
                    postMessage("当前书籍已缓存");
                }
                //判断，是否已完成的章节的起始点比新Task大，如果更大则表示新Task中的该章节已被加载，所以需要剪切
                else if(downloadTask.getLastChapter() >
                        (newTask.getLastChapter() - newTask.getBookChapterList().size())){
                    //删除掉已经完成的章节
                    List<BookChapterBean> remainChapterBeans = newTask.getBookChapterList()
                            .subList(downloadTask.getLastChapter(),
                                    newTask.getLastChapter());
                    String taskName = newTask.getTaskName()
                            + getString(R.string.nb_download_chapter_scope,
                            downloadTask.getLastChapter(), newTask.getLastChapter());
                    //重置任务
                    newTask.setBookChapters(remainChapterBeans);
                    newTask.setTaskName(taskName);

                    //发送添加到任务的提示
                    postMessage("成功添加到缓存队列");
                }
            }
            //表示该任务已经在 下载、等待、暂停、网络错误中
            else {
                isExist = true;
                //发送回去:已经在加载队列中。
                postMessage("任务已存在");
            }
        }
        //重置名字
        if (!isExist){
            String taskName = newTask.getTaskName()
                    + getString(R.string.nb_download_chapter_scope,
                    1, newTask.getLastChapter());
            newTask.setTaskName(taskName);
            postMessage("成功添加到缓存队列");
        }
        return isExist;
    }

    private void addToExecutor(DownloadTaskBean taskEvent){

        //判断是否为轮询请求
        if (!TextUtils.isEmpty(taskEvent.getBookId())) {

            if (!mDownloadTaskList.contains(taskEvent)){
                //加入总列表中，表示创建，修改CollBean的状态。
                mDownloadTaskList.add(taskEvent);
            }
            // 添加到下载队列
            mDownloadTaskQueue.add(taskEvent);
        }

        // 从队列顺序取出第一条下载
        if (mDownloadTaskQueue.size() > 0 && !isBusy) {
            isBusy = true;
            executeTask(mDownloadTaskQueue.get(0));
        }
    }

    private void executeTask(DownloadTaskBean taskEvent){
        Runnable runnable = () -> {

            taskEvent.setStatus(DownloadTaskBean.STATUS_LOADING);

            int result = LOAD_NORMAL;
            List<BookChapterBean> bookChapterBeans = taskEvent.getBookChapters();

            //调用for循环，下载数据
            for (int i=taskEvent.getCurrentChapter(); i<bookChapterBeans.size();++i) {

                BookChapterBean bookChapterBean = bookChapterBeans.get(i);
                //首先判断该章节是否曾经被加载过 (从文件中判断)
                if (BookManager
                        .isChapterCached(taskEvent.getBookId(),bookChapterBean.getTitle())){

                    //设置任务进度
                    taskEvent.setCurrentChapter(i);

                    //章节加载完成
                    postDownloadChange(taskEvent, DownloadTaskBean.STATUS_LOADING, i + "");

                    //无需进行下一步
                    continue;
                }

                //判断网络是否出问题
                if (!NetworkUtils.isAvailable()){
                    //章节加载失败
                    result = LOAD_ERROR;
                    break;
                }

                if (isCancel){
                    result = LOAD_PAUSE;
                    isCancel = false;
                    break;
                }

                //加载数据
                result = loadChapter(taskEvent.getBookId(),bookChapterBean,taskEvent.getResr());
                //章节加载完成
                if (result == LOAD_NORMAL){
                    taskEvent.setCurrentChapter(i);
                    postDownloadChange(taskEvent, DownloadTaskBean.STATUS_LOADING, i + "");
                }
                //章节加载失败
                else {
                    //遇到错误退出
                    break;
                }
            }


            if (result == LOAD_NORMAL){
                //存储DownloadTask的状态
                taskEvent.setStatus(DownloadTaskBean.STATUS_FINISH);//Task的状态
                taskEvent.setCurrentChapter(taskEvent.getBookChapters().size());//当前下载的章节数量
                taskEvent.setSize(BookManager.getBookSize(taskEvent.getBookId()));//Task的大小

                //发送完成状态
                postDownloadChange(taskEvent, DownloadTaskBean.STATUS_FINISH, "下载完成");
            }
            else if (result == LOAD_ERROR){
                taskEvent.setStatus(DownloadTaskBean.STATUS_ERROR);//Task的状态
                //任务加载失败
                postDownloadChange(taskEvent, DownloadTaskBean.STATUS_ERROR, "资源或网络错误");
            }
            else if (result == LOAD_PAUSE){
                taskEvent.setStatus(DownloadTaskBean.STATUS_PAUSE);//Task的状态
                postDownloadChange(taskEvent, DownloadTaskBean.STATUS_PAUSE, "暂停加载");
            }
            else if (result == LOAD_DELETE){
                //没想好怎么做
            }

            //存储状态
            LocalRepository.getInstance().saveDownloadTask(taskEvent);

            //轮询下一个事件，用RxBus用来保证事件是在主线程

            //移除完成的任务
            mDownloadTaskQueue.remove(taskEvent);
            //设置为空闲
            isBusy = false;
            //轮询
            post(new DownloadTaskBean());
        };
        mSingleExecutor.execute(runnable);
    }

    private int loadChapter(String folderName, BookChapterBean bean, String resr){
        //加载的结果参数
        final int[] result = {LOAD_NORMAL};
        getChapterRead(bean.getLink(),folderName,bean,resr);
        return result[0];
    }

    private void postDownloadChange(DownloadTaskBean task,int status,String msg){
        if (mDownloadListener!= null){
            int position = mDownloadTaskList.indexOf(task);
            //通过handler,切换回主线程
            mHandler.post(
                    () -> mDownloadListener.onDownloadChange(
                            position, status, msg)
            );
        }
    }

    private void postMessage(String msg){
        RxBus.getInstance().post(new DownloadMessage(msg));
    }

    private void post(DownloadTaskBean task){
        RxBus.getInstance().post(task);
    }


    @Override
    public boolean onUnbind(Intent intent){

        mDownloadListener = null;
        return super.onUnbind(intent);
    }

    class TaskBuilder extends Binder implements IDownloadManager{
        @Override
        public List<DownloadTaskBean> getDownloadTaskList() {
            return Collections.unmodifiableList(mDownloadTaskList);
        }

        @Override
        public void setOnDownloadListener(OnDownloadListener listener) {
            mDownloadListener = listener;
        }

        @Override
        public void setDownloadStatus(String taskName, int status) {
            //修改某个Task的状态
            switch (status){
                //加入缓存队列
                case DownloadTaskBean.STATUS_WAIT:
                    for (int i=0; i<mDownloadTaskList.size(); ++i){
                        DownloadTaskBean bean = mDownloadTaskList.get(i);
                        if (taskName.equals(bean.getTaskName())){
                            bean.setStatus(DownloadTaskBean.STATUS_WAIT);
                            mDownloadListener.onDownloadResponse(i,DownloadTaskBean.STATUS_WAIT);
                            addToExecutor(bean);
                            break;
                        }
                    }
                    break;
                //从缓存队列中删除
                case DownloadTaskBean.STATUS_PAUSE:
                    Iterator<DownloadTaskBean> it = mDownloadTaskQueue.iterator();
                    while (it.hasNext()){
                        DownloadTaskBean bean = it.next();
                        if (bean.getTaskName().equals(taskName)){
                            if (bean.getStatus() == DownloadTaskBean.STATUS_LOADING
                                    && bean.getTaskName().equals(taskName)){
                                isCancel = true;
                                break;
                            }
                            else{
                                bean.setStatus(DownloadTaskBean.STATUS_PAUSE);
                                mDownloadTaskQueue.remove(bean);
                                int position = mDownloadTaskList.indexOf(bean);
                                mDownloadListener.onDownloadResponse(position,DownloadTaskBean.STATUS_PAUSE);
                                break;
                            }
                        }
                    }
                    break;
            }
        }

        @Override
        public void setAllDownloadStatus(int status) {
            //修改所有Task的状态
        }

        //首先判断是否在加载队列中。
        //如果在加载队列中首先判断是否正在下载，
        //然后判断是否在完成队列中。
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }



    public interface IDownloadManager{
        List<DownloadTaskBean> getDownloadTaskList();
        void setOnDownloadListener(OnDownloadListener listener);
        void setDownloadStatus(String taskName, int status);
        void setAllDownloadStatus(int status);
    }

    public interface OnDownloadListener{
        /**
         *
         * @param pos : Task在item中的位置
         * @param status : Task的状态
         * @param msg: 传送的Msg
         */
        void onDownloadChange(int pos, int status, String msg);

        /**
         * 回复
         */
        void onDownloadResponse(int pos, int status);
    }

    public void getChapterRead(String url, final String  folderName, BookChapterBean bean,String resr) {
        final int[] result = {LOAD_NORMAL};
        Map<String, Object> context2 = new HashMap<String, Object>();
        try {
            com.alibaba.fastjson.JSONObject restrs = com.alibaba.fastjson.JSONObject.parseObject(resr);
            context2.put("aid",bean.getAid());
            String loadUrls;
            if (bean.getLink().indexOf("https") != -1) {
                loadUrls =bean.getLink();
            } else {
                if (bean.getLink().indexOf("qidian.com") != -1) {
                    loadUrls = bean.getLink().replace("http", "https");
                } else {
                    loadUrls = bean.getLink();
                }
            }
            context2 = new SiteHelper(restrs).executeChapter(context2,loadUrls);
            int i=0;
            while (true) {
                i++;
                String body = "";
                if (!context2.get("content").equals("")||context2.get("content")!=null) {
                    if (context2.get("content").getClass() == JSONObject.class) {
                        JSONObject contentJson = (JSONObject) context2.get("content");
                        body = contentJson.getString("text");
                    } else {
                        Object content = (String) context2.get("content");
                        body = content.toString();
                    }
                    ChapterInfoBean infoBean = new ChapterInfoBean();
                    infoBean.setBody(body);
                    BookRepository.getInstance()
                            .saveChapterInfo(folderName, bean.getTitle(),infoBean.getBody());
                    i=0;
                    break;
                }else {
                    Thread.sleep(1000);
                    i++;
                }
                if(i==5){
                    result[0]=LOAD_ERROR;
                    break;
                }
            }


        } catch (Exception e) {
            e.printStackTrace();
           result[0]=LOAD_ERROR;
        }

//        try {
//            mOkHttpClient = new OkHttpClient.Builder()
//                    .connectTimeout(30, TimeUnit.SECONDS)       //设置连接超时
//                    .readTimeout(60, TimeUnit.SECONDS)          //设置读超时
//                    .writeTimeout(60, TimeUnit.SECONDS)          //设置写超时
//                    .retryOnConnectionFailure(true)             //是否自动重连
//                    .build();
//            final Request request = new Request.Builder()
//                    .url(UeHttpUrl.getChapterRead() + url)
//                    .get()
//                    .build();
//            Call call = mOkHttpClient.newCall(request);
//            call.enqueue(new Callback() {
//                @Override
//                public void onFailure(Call call, IOException e) {
//
//                }
//
//                @Override
//                public void onResponse(Call call, Response response) throws IOException {
//                    String str = response.body().string();
//                    String headers[] = null;
//                    try {
//                        com.alibaba.fastjson.JSONObject restr = com.alibaba.fastjson.JSONObject.parseObject(str);
//                        if (restr.get("failed") != null) {
//                            handler.post(runnableUi);
//                        } else {
//                            helper = new SiteHelper(restr);
//                            Map<String, Object> contexts = new HashMap<String, Object>();
//                            contexts.put("aid", aid);
//                            contexts = helper.executeMulu(contexts, restr.getString("testUrl"));
//                            Object[] chapters = (Object[]) contexts.get("chapters");
//                            if (chapters != null) {
//                                for (Object o : chapters) {
//                                    com.alibaba.fastjson.JSONObject cJson = (com.alibaba.fastjson.JSONObject) o;
//                                    if (!cJson.getString("vip").equals("true")) {
//                                        BookChapterBean chapterBean = new BookChapterBean();
//                                        chapterBean.setBookId(bookId);
//                                        chapterBean.setLink(cJson.getString("url"));
//                                        chapterBean.setTitle(cJson.getString("name"));
//                                        mChapterList.add(chapterBean);
//                                    }
//                                }
//                            }
//                            showCategory(mChapterList);
//                        }
//                    } catch (Exception e1) {
//                        e1.printStackTrace();
//                    }
//                }
//            });
//        } catch (Exception e) {
//        }
    }
    public boolean isEven01(int num) {
        if (num % 2 == 0) {
            return true;
        } else {
            return false;
        }
    }

}
